package com.starlinkdt.framework.aspectj;

import com.starlinkdt.common.annotation.SignUrl;
import com.starlinkdt.common.storage.StorageUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class OssUrlAspect {

    @Around("execution(* com.starlinkdt.api.controller.admin.energy..*.getInfo(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        if (result instanceof Map) {
            Map<String, Object> resultMap = (Map<String, Object>) result;
            Object data = resultMap.get("data");
            if (data != null) {
                processResult(data);
            }
        } else {
            processResult(result);
        }
        return result;
    }

    private void processResult(Object result) {
        if (result instanceof List) {
            for (Object obj : (List<?>) result) {
                processObject(obj);
            }
        } else {
            processObject(result);
        }
    }

    private void processObject(Object obj) {
        Class<?> clazz = obj.getClass();
        // 递归找寻父类的属性，不会造成死循环，最上层的类是object
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(SignUrl.class)) {
                    field.setAccessible(true);
                    SignUrl annotation = field.getAnnotation(SignUrl.class);
                    String objField = annotation.objField();
                    try {
                        Field targetField = clazz.getDeclaredField(objField);
                        targetField.setAccessible(true);
                        if (annotation.hide()) {
                            field.set(obj, null);
                        }
                        String objectVal = (String) targetField.get(obj);
                        if (objectVal != null && !objectVal.isEmpty()) {
                            String url = new StorageUtils().getObjectSignUrl(objectVal);
                            field.set(obj, url);
                        }
                    } catch (NoSuchFieldException | IllegalAccessException e) {
                        log.error("OSS Url Mapping-> {}", e.getMessage());
                    }
                }
            }
            // 向上查找父类
            clazz = clazz.getSuperclass();
        }
    }
}
